﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using MvdDonk.Bomberman.Network;
using System.Net;
using MvdDonk.Bomberman.Network.Events;

namespace MvdDonk.Bomberman.Managers
{
    class NetworkManager
    {
        //public delegate void ServerFoundEventHandler(object sender, ServerFoundEventArgs e);
        //public event ServerFoundEventHandler ServerFound;

        private const string AppIdentifier = "MvdDonk.Bomberman";
        private const int ServerPort = 16739;
        private Server _Server;
        public Server Server
        {
            get
            {
                return _Server;
            }
        }

        private Client _Client;
        public Client Client
        {
            get
            {
                if (_Client == null)
                {
                    _Client = new Client(AppIdentifier, ServerPort, Environment.MachineName);
                    _Client.ServerFound += new Network.Client.ServerFoundEventHandler(Client_ServerFound);
                }
                return _Client;
            }
        }


        //TODO Should be in the client not here!
        public Dictionary<string, IPEndPoint> ServersFound { get; private set; }

        public bool StartServer()
        {
            try
            {
                _Server = new Server(AppIdentifier, ServerPort, Environment.MachineName + "_Server");
            }
            catch
            {
                _Server = null;
                if (Bomberman.Instance.DebugEnabled)
                    throw;
            }
            return _Server != null;
        }


        //public void StartGame()
        //{
        //    _Server.StartGame();
        //}

        public void FindServers()
        {
            ServersFound = new Dictionary<string, IPEndPoint>();
            Client.FindServers();
        }

        public void JoinServer(IPEndPoint endPoint)
        {
            Client.Connect(endPoint);
            Client.MovementUpdate += new Client.MovementUpdateEventHandler(client_MovementUpdate);
            Client.PositionSync += new Client.PositionSyncEventHandler(client_PositionSync);
        }

        void client_PositionSync(object sender, PositionSyncEventArgs e)
        {
            //if (!e.IsLocalPlayer)
            //{
            var entity = Bomberman.Instance.EntityManager.Players.FirstOrDefault(ent => ent.NetworkId == e.Id);
            if (entity == null)//Perhaps new player, create him
            {
                entity = new Entities.Player(Bomberman.Instance.TestPlayerTexture, e.Position, e.Id, "NA");
                Bomberman.Instance.EntityManager.AddPlayer(entity);
            }

            entity.Position = e.Position;
            //}
        }

        void client_MovementUpdate(object sender, MovementUpdateEventArgs e)
        {

            if (e.IsLocalPlayer)
            {
                //localPlayerRef.Position = e.Position;
            }
            else
            {
                var entity = Bomberman.Instance.EntityManager.Players.FirstOrDefault(ent => ent.NetworkId == e.Id);
                if (entity == null)//Perhaps new player, create him
                {
                    entity = new Entities.Player(Bomberman.Instance.TestPlayerTexture, new Vector2(0, 0), e.Id, "NA");
                    Bomberman.Instance.EntityManager.AddPlayer(entity);
                }

                entity.MovementState = e.MovementState;
                entity.MovementVector = e.MovementVector;
            }
        }

        public void Update(GameTime gameTime)
        {
            if (_Server != null)
                _Server.Poll();
            if (_Client != null)
                _Client.Poll();
        }

        public void KillClient()
        {
            if (_Client != null)
            {
                _Client.Disconnect();
                _Client = null;
            }
        }

        public void KillServer()
        {
            if (_Server != null)
            {
                _Server.Shutdown();
                _Server = null;
            }
        }

        #region Events
        void Client_ServerFound(object sender, ServerFoundEventArgs e)
        {
            if (ServersFound.ContainsKey(e.ServerName))
                ServersFound.Remove(e.ServerName);
            ServersFound.Add(e.ServerName, e.EndPoint);

            //if (ServerFound != null)
            //    ServerFound(this, e);
        }


        #endregion
    }
}
